﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using CSharp.Libs.ExceptionHandling;
using System.Collections.Specialized;
using CSharp.Libs.Net;
using CSharp.Libs.Misc;

namespace CSharp.Libs.Koc.Models
{
    public class PhpCommand : IDisposable
    {
        #region declarations
        private ExceptionCollector _EC = null;

        private String _strPhpUrlPrefix = "";
        private String _strPhpUrlServerId = "";
        private String _strPhpUrlDirs = "";
        private String _strPhpCommand = "";
        private Dictionary<String, String> _dictParameters = null;
        private NameValueCollection _nvcParameters = null;
        #endregion



        #region constructor / terminator
        public PhpCommand(
            ExceptionCollector EC)
        {
            _EC = EC;
            _dictParameters = new Dictionary<String, String>();
            _nvcParameters = new NameValueCollection();
        }

        ~PhpCommand()
        {
        }

        public void Dispose()
        {
            _dictParameters = null;
            _nvcParameters = null;
            _EC = null;
        }
        #endregion



        #region private functions
        /// <summary>_Reset</summary>
        /// <remarks>clears all parameters of the URL</remarks>
        /// <history>created  12.01.2012 </history>
        private void _Reset()
        {
            try
            {
                _strPhpUrlPrefix = "";
                _strPhpUrlServerId = "";
                _strPhpUrlDirs = "";
                _strPhpCommand = "";

                _dictParameters.Clear();
                _nvcParameters.Clear();
            }
            catch (Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }
        }

        /// <summary>_GetURL</summary>
        /// <remarks>puts together the complete URL string and 
        /// prepares the NameValueCollection for the POST body</remarks>
        /// <returns>the complete URL string</returns>
        /// <history>created  12.01.2012 </history>
        private String _GetURL()
        {
            try
            {
                // validate URL
                if (_strPhpUrlPrefix.Trim() == "" ||
                    _strPhpUrlServerId.Trim() == "" ||
                    _strPhpUrlDirs.Trim() == "" ||
                    _strPhpCommand.Trim() == "" ||
                    _dictParameters.Count <= 2)
                {
                    return "";
                }

                // put together URL
                String strURL = String.Concat(
                    _strPhpUrlPrefix,
                    _strPhpUrlServerId,
                    _strPhpUrlDirs,
                    _strPhpCommand,
                    "?");

                _nvcParameters.Clear();

                // add parameters
                foreach (KeyValuePair<String, String> KVP in _dictParameters)
                {
                    _nvcParameters.Add(KVP.Key, KVP.Value);
                    strURL = String.Concat(strURL,
                        KVP.Key, "=", 
                        KVP.Value, "&");
                }

                strURL = strURL.TrimEnd('&');

                return strURL;
            }
            catch (Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }

            return "";
        }

        /// <summary>_PostURL</summary>
        /// <returns></returns>
        /// <history>created  12.01.2012 </history>
        private String _PostURL()
        {
            try
            {
                String URL = _GetURL();
                String Answer = "";

                if (URL.Trim() != "")
                {
                    //KocPostSubmitter KPS = new KocPostSubmitter();

                    PostSubmitter PS = new PostSubmitter(URL);
                    PS.Type = PostSubmitter.PostTypeEnum.Post;
                    PS.PostItems = _nvcParameters;
                    Answer = PS.Post();
                    PS = null;
                }

                return Answer;
            }
            catch (Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }

            return "";
        }

        /// <summary>_GetAnswerHashtable</summary>
        /// <param name="htRet"></param>
        /// <returns></returns>
        /// <history>created  12.01.2012 </history>
        private Boolean _GetAnswerHashtable(
            out Hashtable htRet)
        {
            htRet = null;

            try
            {
                String strResponse = "";
                
                strResponse = _PostURL();

                if (strResponse != "")
                {
                    htRet = JSON.JsonDecode(strResponse) as Hashtable;
                    if (htRet != null &&
                        htRet["ok"] != null)
                    {
                        if (htRet["ok"] is Boolean)
                        {
                            return (Boolean)htRet["ok"];
                        }
                        else if (htRet["ok"] is String)
                        {
                            return Boolean.Parse(htRet["ok"].ToString());
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }

            return false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="htRet"></param>
        /// <param name="strRet"></param>
        /// <returns></returns>
        /// <history>created  08.03.2012 </history>
        private Boolean _GetAnswerHashtableAndString(
            out Hashtable htRet,
            out String strRet)
        {
            htRet = null;
            strRet = "";

            try
            {
                String strResponse = "";

                strResponse = _PostURL();
                strRet = strResponse;

                if (strResponse != "")
                {
                    htRet = JSON.JsonDecode(strResponse) as Hashtable;
                    if (htRet != null &&
                        htRet["ok"] != null)
                    {
                        if (htRet["ok"] is Boolean)
                        {
                            return (Boolean)htRet["ok"];
                        }
                        else if (htRet["ok"] is String)
                        {
                            return Boolean.Parse(htRet["ok"].ToString());
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }

            return false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="NumberString"></param>
        /// <returns></returns>
        private Boolean IsNumber(
            String NumberString)
        {
            try
            {
                Double DBL = 0;
                return Double.TryParse(NumberString, out DBL);
            }
            catch(Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }

            return false;
        }

        /// <summary>_GetParameterValueInt32</summary>
        /// <param name="ParameterName"></param>
        /// <returns></returns>
        /// <history>01.06.2011</history>
        private Int32 _GetParameterValueInt32(
            String ParameterKey)
        {
            try
            {
                Int32 retVal = 0;
                Int32.TryParse(_GetParameterValueString(ParameterKey), out retVal);

                return retVal;
            }
            catch (Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }

            return 0;
        }

        /// <summary>_GetParameterValueString</summary>
        /// <param name="ParameterKey"></param>
        /// <returns></returns>
        /// <history>01.06.2011</history>
        private String _GetParameterValueString(
            String ParameterKey)
        {
            try
            {
                if (_dictParameters.ContainsKey(ParameterKey))
                {
                    return _dictParameters[ParameterKey].ToString();
                }
            }
            catch (Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }

            return "";
        }
        #endregion



        #region interface
        #region properties
        public String PhpUrlPrefix
        {
            get
            {
                return _strPhpUrlPrefix;
            }
            set
            {
                _strPhpUrlPrefix = value;
            }
        }

        public Int32 PhpUrlServerId
        {
            get
            {
                if (IsNumber(_strPhpUrlServerId))
                {
                    return Int32.Parse(_strPhpUrlServerId);
                }
                else
                {
                    return 0;
                }
            }
            set
            {
                if (value > 0 && value <= constants.MAX_SERVER_NUMBER)
                {
                    _strPhpUrlServerId = value.ToString();
                }
            }
        }

        public String PhpUrlDirs
        {
            get
            {
                return _strPhpUrlDirs;
            }
            set
            {
                _strPhpUrlDirs = value;
            }
        }

        public String PhpCommandString
        {
            get
            {
                return _strPhpCommand;
            }
            set
            {
                _strPhpCommand = value;
            }
        }
        
        public Dictionary<String, String> Parameters
        {
            get
            {
                return _dictParameters;
            }
            set
            {
                _dictParameters = value;
            }
        }
        #endregion

        #region methods
        public void Reset()
        {
            _Reset();
        }

        public String GetURL()
        {
            return _GetURL();
        }

        public String PostURL()
        {
            return _PostURL();
        }

        public Boolean GetAnswerHashtable(
            out Hashtable htRet)
        {
            return _GetAnswerHashtable(out htRet);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="htRet"></param>
        /// <param name="strRet"></param>
        /// <returns></returns>
        /// <history>created  08.03.2012 </history>
        public Boolean GetAnswerHashtableAndString(
            out Hashtable htRet,
            out String strRet)
        {
            return _GetAnswerHashtableAndString(out htRet, out strRet);
        }

        public Int32 GetParameterValueInt32(
            String ParameterKey)
        {
            return _GetParameterValueInt32(ParameterKey);
        }

        public String GetParameterValueString(
            String ParameterKey)
        {
            return _GetParameterValueString(ParameterKey);
        }
        #endregion
        #endregion
    }
}
